package io.github.iogogogo.redis.configuration;

import io.github.iogogogo.redis.properties.RedisInstanceProperties;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.NonNull;

import java.util.Map;
import java.util.Objects;

/**
 * Created by tao.zeng on 2024/11/18.
 */
@Slf4j
public class MultipleRedisConfiguration implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {

    private ApplicationContext applicationContext;

    @Setter
    private RedisInstanceProperties redisInstanceProperties;

    @Override
    public void setBeanName(@NonNull String beanName) {
        log.info("init beanName: {}", beanName);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Objects.requireNonNull(this.applicationContext, "applicationContext is not null.");
        Objects.requireNonNull(this.redisInstanceProperties, "redisInstanceProperties is not null.");
    }

    @Override
    public void postProcessBeanDefinitionRegistry(@NonNull BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        Map<String, RedisProperties> propertiesMap = redisInstanceProperties.getInstances();
        propertiesMap.forEach((k, v) -> {
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(RedisProperties.class, () -> v);

            AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
            // 设置初始化方法和销毁方法
            beanDefinition.setInitMethodName("init");
            beanDefinition.setDestroyMethodName("destroy");

            beanDefinitionRegistry.registerBeanDefinition(String.join("", k, "RedisProperties"), beanDefinition);
        });
    }

    @Override
    public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
